/**
 * C++ Wars ~made by V@ughn
 * ------------------------
 * A win32 2d fighting game! Features 
 * different programming languages as 
 * selectable characters!
 *
 * Current files included:
 * ----------------------
 * main.h
 * main.cpp
 * menuitem.h
 * menuitem.cpp
 * object.h
 * background.h
 *
 * Last time edited->March 20, 2012
 * --------------------------------
 *
 */

/********************
 * CURRENT BUILD ID *
 ********************/
const char * BUILD_ID = (char*)"v0.11";

#include "main.h"
#include "menuitem.h"
#include "object.h"
#include "background.h"


int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	hge = hgeCreate(HGE_VERSION);
	hge->System_SetState(HGE_LOGFILE, "status.log");
	hge->System_SetState(HGE_FRAMEFUNC, Update);
	hge->System_SetState(HGE_RENDERFUNC, RenderFunc);
	hge->System_SetState(HGE_TITLE, "C++ Wars");
	hge->System_SetState(HGE_WINDOWED, true);
	hge->System_SetState(HGE_SCREENWIDTH, 800);
	hge->System_SetState(HGE_SCREENHEIGHT, 600);
	hge->System_SetState(HGE_SCREENBPP, 32);

	if(hge->System_Initiate())
	{
		//play the menu music to make the logo look cooler ;)
		menu=hge->Effect_Load("resource/sounds/menu.ogg");
		if(!menu) {
			MessageBox(NULL, (LPCSTR)"ERROR LOADING FILES", (LPCSTR)"YOU FAIL XD", MB_OK | MB_ICONERROR | MB_APPLMODAL);
			hge->System_Shutdown();
			hge->Release();
			return 0;
		}
		toggle = hge->Effect_PlayEx(menu, 100, 0, 1.0F, true);

		VAUGHN_LOGO();

		//Load sound and textures
		fnt=new hgeFont("font1.fnt");
		hge->Gfx_BeginScene();
	    hge->Gfx_Clear(0);
		fnt->printf((400), (290), HGETEXT_CENTER, "LOADING");
		hge->Gfx_EndScene();

		quad.tex=hge->Texture_Load("resource/bg.png");
		tex=hge->Texture_Load("resource/cursor.png");
		snd=hge->Effect_Load("resource/sounds/select.ogg");
		level1=hge->Effect_Load("resource/sounds/loop1.ogg");
		level2=hge->Effect_Load("resource/sounds/loop2.ogg");
		level3=hge->Effect_Load("resource/sounds/loop3.ogg");
		level4=hge->Effect_Load("resource/sounds/loop4.ogg");
		jump=hge->Effect_Load("resource/sounds/jump.wav");
		punch1=hge->Effect_Load("resource/sounds/punch1.ogg");
		punch2=hge->Effect_Load("resource/sounds/punch2.ogg");
		slap=hge->Effect_Load("resource/sounds/slap.ogg");
		if(!quad.tex || !tex || !snd || !level1 || !level2 || !level3 || !punch1
			|| !level4 || !jump || !punch2 || !slap){
			MessageBox(NULL, (LPCSTR)"ERROR LOADING FILES", (LPCSTR)"YOU FAIL XD", MB_OK | MB_ICONERROR | MB_APPLMODAL);
			hge->System_Shutdown();
			hge->Release();
			return 0;
		}

		//create cursor sprite
		spr=new hgeSprite(tex,0,0,32,32);

		// Set up the quad we will use for background animation
		quad.blend=BLEND_ALPHABLEND | BLEND_COLORMUL | BLEND_NOZWRITE;

		for(int i=0;i<4;i++)
		{
			// Set up z-coordinate of vertices
			quad.v[i].z=0.5f;
			// Set up color. The format of DWORD col is 0xAARRGGBB
			quad.v[i].col=0xFFFFFFFF;
		}
		quad.v[0].x=0; quad.v[0].y=0; 
		quad.v[1].x=800; quad.v[1].y=0; 
		quad.v[2].x=800; quad.v[2].y=600; 
		quad.v[3].x=0; quad.v[3].y=600; 

		// Create and initialize the GUI
		gui=new hgeGUI();

		gui->AddCtrl(new hgeGUIMenuItem(1,fnt,snd,400,200,0.0f,"Play"));
		gui->AddCtrl(new hgeGUIMenuItem(2,fnt,snd,400,240,0.1f,"Info"));
		gui->AddCtrl(new hgeGUIMenuItem(3,fnt,snd,400,280,0.2f,"Help"));
		gui->AddCtrl(new hgeGUIMenuItem(4,fnt,snd,400,320,0.3f,"Credits"));
		gui->AddCtrl(new hgeGUIMenuItem(5,fnt,snd,400,360,0.4f,"Exit"));
		showCredits = false;
		beginGame = false;
		
		gui->SetNavMode(HGEGUI_UPDOWN | HGEGUI_CYCLED);
		gui->SetCursor(spr);
		gui->SetFocus(1);
		gui->Enter();

		//create the player
	    player.CreateObject(CPLUSPLUS_GUY);
	    player.CreateImage(CPLUSPLUS_GUY);

		// Let's rock now!
		hge->System_Start();

		// Delete created objects and free loaded resources
		delete gui;
		delete fnt;
		delete spr;
		hge->Effect_Free(snd);
		hge->Effect_Free(menu);
		hge->Effect_Free(level1);
		hge->Effect_Free(level2);
		hge->Effect_Free(level3);
		hge->Effect_Free(level4);
		hge->Texture_Free(tex);
		hge->Texture_Free(quad.tex);
	}

	// Clean up and shutdown
	hge->System_Shutdown();
	hge->Release();
	return 0;
}

bool Update()
{
	float dt=hge->Timer_GetDelta();
	static float t=0.0f;
	float tx,ty;
	int id;
	static int lastid=0;

	// If ESCAPE was pressed, tell the GUI to finish
	if(hge->Input_GetKeyState(HGEK_ESCAPE)) {
		if(beginGame){hge->Channel_Stop(toggle); toggle = hge->Effect_PlayEx(menu, 100, 0, 1.0F, true);}
		showCredits = false; 
		showHelp = false;
		showInfo = false;
		beginGame = false;
		gui->ShowCtrl(1, true);
		gui->ShowCtrl(2, true);
		gui->ShowCtrl(3, true);
		gui->ShowCtrl(4, true);
		gui->ShowCtrl(5, true);
		gui->SetFocus(1); 
		gui->Enter();
	}

	// We update the GUI and take an action if
	// one of the menu items was selected
	id=gui->Update(dt);

	if(id == -1 && !beginGame)
	{
		switch(lastid)
		{
			case 1:
				gui->Leave();
				hge->Channel_Stop(toggle); toggle = 0;
				toggle = hge->Effect_PlayEx(level1, 100, 0, 1.0F, true);
				beginGame = true;
				break;
			case 2:
				gui->Leave();
				showInfo = true;
				break;
			case 3:
				gui->Leave();
				showHelp = true;
				break;
			case 4:
				gui->Leave();
                showCredits = true;
				break;

			case 5: return true;
		}
	}
	else if(id) { lastid=id; gui->Leave(); }

	// Here we update our background animation
	t+=dt;
	tx=50*cosf(t/60);
	ty=50*sinf(t/60);

	quad.v[0].tx=tx;        quad.v[0].ty=ty;
	quad.v[1].tx=tx+800/64; quad.v[1].ty=ty;
	quad.v[2].tx=tx+800/64; quad.v[2].ty=ty+600/64;
	quad.v[3].tx=tx;        quad.v[3].ty=ty+600/64;

	return false;
}

bool RenderFunc()
{
	hge->Gfx_BeginScene();
	hge->Gfx_Clear(WHITE);
	if(!beginGame)hge->Gfx_RenderQuad(&quad);
	gui->Render();
	fnt->SetColor(0xFFFFFFFF);
	
	if(showHelp){
		gui->ShowCtrl(1, false);
		gui->ShowCtrl(2, false);
		gui->ShowCtrl(3, false);
		gui->ShowCtrl(4, false);
		gui->ShowCtrl(5, false);
		fnt->printf(400, 150, HGETEXT_CENTER, "Help");
	    fnt->printf(400, 190, HGETEXT_CENTER, "Use arrow keys to move");
	    fnt->printf(400, 230, HGETEXT_CENTER, "Use space bar or left click to shoot");
	    fnt->printf(400, 270, HGETEXT_CENTER, "Use upper arrow key to jump");
		fnt->printf(400, 320, HGETEXT_CENTER, "Use enter key to pause");
	    fnt->printf(400, 500, HGETEXT_CENTER, "(press escape to go back)");
	}

	/* SHOW CREDITS */
	if(showCredits){
		gui->ShowCtrl(1, false);
		gui->ShowCtrl(2, false);
		gui->ShowCtrl(3, false);
		gui->ShowCtrl(4, false);
		gui->ShowCtrl(5, false);
		fnt->printf(400, 150, HGETEXT_CENTER, "C++ Wars");
	    fnt->printf(400, 190, HGETEXT_CENTER, "made by V@ughn");
	    fnt->printf(400, 240, HGETEXT_CENTER, "Special thanks:");
	    fnt->printf(400, 280, HGETEXT_CENTER, "Jerret and Nigel");
	    fnt->printf(400, 500, HGETEXT_CENTER, "(press escape to go back)");
	}

	/* SHOW INFO */
	if(showInfo){
		gui->ShowCtrl(1, false);
		gui->ShowCtrl(2, false);
		gui->ShowCtrl(3, false);
		gui->ShowCtrl(4, false);
		gui->ShowCtrl(5, false);
		SHOW_INFO();
	}

	/* PLACE ALL THE GAME CODE HERE */
	if(beginGame)
	{
		gui->ShowCtrl(1, false);
		gui->ShowCtrl(2, false);
		gui->ShowCtrl(3, false);
		gui->ShowCtrl(4, false);
		gui->ShowCtrl(5, false);

		//set up enemy based on level
		if(round == 1)      {if(!levelStarted){enemy.CreateObject(DOSBATCH_GUY);    enemy.CreateImage(DOSBATCH_GUY);    levelStarted = true;}}
		else if(round == 2) {if(!levelStarted){enemy.CreateObject(BASH_GUY);        enemy.CreateImage(BASH_GUY);        levelStarted = true;}}
		else if(round == 3) {if(!levelStarted){enemy.CreateObject(DCL_GUY);         enemy.CreateImage(DCL_GUY);         levelStarted = true;}}
		else if(round == 4) {if(!levelStarted){enemy.CreateObject(BASIC_GUY);       enemy.CreateImage(BASIC_GUY);       levelStarted = true;}}
		else if(round == 5) {if(!levelStarted){enemy.CreateObject(SMALLTALK_GUY);   enemy.CreateImage(SMALLTALK_GUY);   levelStarted = true;}}
		else if(round == 6) {if(!levelStarted){enemy.CreateObject(VISUALBASIC_GUY); enemy.CreateImage(VISUALBASIC_GUY); levelStarted = true;}}
		else if(round == 7) {if(!levelStarted){enemy.CreateObject(PASCAL_GUY);      enemy.CreateImage(PASCAL_GUY);      levelStarted = true;}}
		else if(round == 8) {if(!levelStarted){enemy.CreateObject(RUBYONRAILS_GUY); enemy.CreateImage(RUBYONRAILS_GUY); levelStarted = true;}}
		else if(round == 9) {if(!levelStarted){enemy.CreateObject(LUA_GUY);         enemy.CreateImage(LUA_GUY);         levelStarted = true;}}
		else if(round == 10){if(!levelStarted){enemy.CreateObject(PYTHON_GUY);      enemy.CreateImage(PYTHON_GUY);      levelStarted = true;}}
		else if(round == 11){if(!levelStarted){enemy.CreateObject(C_GUY);           enemy.CreateImage(C_GUY);           levelStarted = true;}}
		else if(round == 12){if(!levelStarted){enemy.CreateObject(OBJECTIVEC_GUY);  enemy.CreateImage(OBJECTIVEC_GUY);  levelStarted = true;}}
		else if(round == 13){if(!levelStarted){enemy.CreateObject(JAVA_GUY);        enemy.CreateImage(JAVA_GUY);        levelStarted = true;}}
		else if(round == 14){if(!levelStarted){enemy.CreateObject(CSHARP_GUY);      enemy.CreateImage(CSHARP_GUY);      levelStarted = true;}}
        else if(round == 15){if(!levelStarted){enemy.CreateObject(NASM_GUY);        enemy.CreateImage(NASM_GUY);        levelStarted = true;}}
		else if(round > 15) round = 1;

		//update player
		player.UpdatePlayerStats();
		player.Update();

		//update enemy
		enemy.Update(1, true); 
		enemy.UpdateEnemy();
	}

	hge->Gfx_EndScene();

	return false;
}

void VAUGHN_LOGO( void )
{
	TEXTURE skin =hge->Texture_Load("resource/logo.png");
	IMAGE * logo = new hgeSprite(skin,0,0,480, 272);

	if(!logo){
		MessageBox(NULL, (LPCSTR)"Can't find logo image! Shutting down...", (LPCSTR)"Error", MB_OK | MB_ICONERROR | MB_APPLMODAL);
		hge->System_Shutdown();
		hge->Release();
		return;
	}

	for(int i = 0; i < 650; i++)
	{
		hge->Gfx_BeginScene();
	    hge->Gfx_Clear(0);
        logo->Render(147,170);
        hge->Gfx_EndScene();
	}

	delete logo;
	hge->Texture_Free(skin);

	return;
}

void SHOW_INFO()
{
	if(hge->Input_GetKeyState(HGEK_RIGHT) && nav < 16){
		hge->Effect_Play(snd);
        nav++; 
		loadedNav = false;
	}
	else if(hge->Input_GetKeyState(HGEK_LEFT) && nav > 1) {
		hge->Effect_Play(snd); 
		nav--; 
		loadedNav = false;
	}

	if(!loadedNav){
		display.CreateImage(nav);
		display.CreateObject(nav);
	}

	display.Update(0);
	display.position = STILL;
	display.Xposition = 300;
	display.Yposition =150;
	fnt->SetColor(WHITE);
	fnt->printf(400, 100, HGETEXT_CENTER, "%s", display.name);
	fnt->printf(50, 230, HGETEXT_CENTER, "<");
	fnt->printf(750, 230, HGETEXT_CENTER, ">");
    fnt->printf(400, 250, HGETEXT_CENTER, "%s", display.info);
	fnt->printf(400, 290, HGETEXT_CENTER, "%s", display.info2);
	fnt->printf(400, 330, HGETEXT_CENTER, "%s", display.info3);
	fnt->printf(400, 370, HGETEXT_CENTER, "%s", display.info4);
	fnt->printf(400, 500, HGETEXT_CENTER, "(press escape to go back)");

	return;
}